使用Minio-Operator搭建MinIO集群


服务器准备

  1. 准备4台服务器
  2. 安装ubuntu18
  3. 设置hostname分别为node1~node4
  4. 装好k8s(3个master节点,1个node节点)

磁盘准备

每台服务器准备n块数据盘,例如4块,格式化为xfs,每一块盘都要执行:

mkfs.xfs /dev/sdb -L MINIO-DISK1
mkfs.xfs /dev/sdc -L MINIO-DISK2
mkfs.xfs /dev/sdd -L MINIO-DISK3
mkfs.xfs /dev/sde -L MINIO-DISK4

vim /etc/fstab:

LABEL=MINIO-DISK1        /data/minio/data-1     xfs     defaults,noatime  0       2
LABEL=MINIO-DISK2        /data/minio/data-2     xfs     defaults,noatime  0       2
LABEL=MINIO-DISK3        /data/minio/data-3     xfs     defaults,noatime  0       2
LABEL=MINIO-DISK4        /data/minio/data-4     xfs     defaults,noatime  0       2

挂载

sudo mount -a

可以考虑下inode数量,使用df -i查看磁盘最大inodes数,将来如果不够用了,可以使用以下命令动态扩容:

# 使用10%的容量用于存放inodes
sudo xfs_growfs -m 10 /data/minio/data-1/

创建minio存储pv

给每一个磁盘创建一个pv,假设我们有4台服务器,每一台服务器有4个硬盘。

创建pv有两种方式,一种是使用官方提供的minio/directpv,它会自动识别硬盘并创建pv,本人没用过,就不提了。

另一种是手动创建pv,具体步骤如下:

创建minio-storageclass.yaml,并执行kubectl apply -f minio-storageclass.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: minio-local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

前面已经将硬盘都挂载到4台服务器上了,目录分别为

  1. /data/minio/data-1
  2. /data/minio/data-2
  3. /data/minio/data-3
  4. /data/minio/data-4

给16个硬盘创建16个pv的yaml文件,并执行kubectl apply -f pv-xxx.yaml,其中node1的第一个pv内容如下:

apiVersion: v1
kind: PersistentVolume
metadata:
   name: minio-pv-node1-1
spec:
   capacity:
      storage: 1Ti
   volumeMode: Filesystem
   accessModes:
   - ReadWriteOnce
   persistentVolumeReclaimPolicy: Retain # 删除持久卷时保留数据
   storageClassName: minio-local-storage
   local:
      path: /data/minio/data-1
   nodeAffinity:
     required:
       nodeSelectorTerms:
       - matchExpressions:
         - key: kubernetes.io/hostname
           operator: In
           values:
           - node1

其他15个按照以上模板,其中需要修改的字段有:

  1. metadata.name:pv名称,格式为minio-pv-{node hostname}-{1-4}
  2. spec.capacity.storage: 磁盘大小
  3. local.path:对应的磁盘挂载路径,格式为/data/minio-data-{1-4}
  4. 最后一行的node1,当前服务器hostname

由于pv数量可以比较多,需要修改的部分都是比较有规律的,可以自行写个脚本快速生成。

创建local-path pv

已经为minio存储创建了pv,为啥还需要local-path pv呢?因为集群部署minio默认会开启审计功能以及prometheus监控,这两个模块也是需要存储的。

minio数据存储一般都是比较大的硬盘,如果也单独为这两个模块准备大硬盘实在不划算,所以需要为他们单独准备存储。

如果你有额外的数据盘就再好不过,如果没有,系统盘足够大也可以。

具体步骤参考:使用Pocal-Path-Provisioner动态创建本地磁盘pv

集群部署

安装Operator

wget https://github.com/minio/operator/releases/download/v4.4.28/kubectl-minio_4.4.28_linux_amd64 -O kubectl-minio
chmod +x kubectl-minio
mv kubectl-minio /usr/local/bin/

# 检查安装
kubectl minio version

# 初始化,默认初始到minio-operator这个命名空间
kubectl minio init

# 查看,等服务都Running
kubectl get all --namespace minio-operator

临时代理一个端口访问operator控制台

kubectl minio proxy

该命令会打印出访问控制台所需要的JWT:

创建租户

我们可以在operator控制台页面上创建租户,基本上是傻瓜式操作,自己看一眼就知道怎么操作了。

也可以使用命令行方式,但是实测发现命令行方式功能不全,可配置项没有页面上多。

要用哪种方式自行决定,这里两种方式都介绍一下

页面方式

使用上面拿到的地址和JWT登录operator页面,点击右上角create tenant

下图Expose是指用loadbalance方式暴露服务,我没有云负载均衡,所以不勾选:

配置镜像版本,可以使用默认:

pod调度相关配置:

用户相关,可以把这里默认的用户的账号密码记下来,之后登录控制台或s3/sdk访问minio都可以用这个账号。

是否启用tls,根据你自己需要选择:

是否加密:

审计日志,你可以选择关闭,如果启用,storage class选一个别的存储,不要用minio专用磁盘。

我本地创建了一个local-path的存储,可以参考:使用local-path-provisioner动态创建本地磁盘pv

prometheus监控,与审计日志一样,可以不用,用的话选一个存储:

点击右下角创建,记下租户的Access KeySecret Key,控制台登录或SDK访问就用这个账号密码。

这就创建好了,可以通过命令行查看pod状态。

命令行方式

# 给租户创建单独的namespace
kubectl create namespace minio-tenant-1

# 创建租户
kubectl minio tenant create minio-tenant-1       \
  --servers                 4                    \
  --volumes                 16                   \
  --capacity                16Ti                 \
  --storage-class           minio-local-storage    \
  --namespace               minio-tenant-1

常用参数:

参数 含义
–disable-tls 关闭tls
enable-audit-logs 是否启用审计,默认开启。启用审计时,需要准备额外存储给审计用。
这里有个奇怪的bug,必须用--enable-audit-logs=false,不能用enable-audit-logs false
servers 服务器总数
volumes 硬盘总数(4台服务器,每台4块盘)
capacity 容量总数(假设一块磁盘1T,共16块)
storage-class 存储类,使用刚才创建的minio-local-storage
namespace 租户命名空间

其他参数:

可以从命令行参数列表中看出命令行工具其实功能是不全的,因此建议使用页面操作。

创建成功后,会打印出租户的用户名密码,拿个小本本记一下,控制台登录或SDK访问就用这个账号密码。

刚执行完create,使用kubectl get pods -n minio-tenant-1可能看不到minio相关pod,需要稍等一小会,minio-operator会自动把相关pod创建出来。

访问控制台

minio租户默认情况只能在集群内部访问:

kubectl get svc --namespace minio-tenant-1

NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
minio                    ClusterIP   10.109.88.X     <none>        443/TCP             137m
minio-tenant-1-console   ClusterIP   10.97.87.X      <none>        9090/TCP,9443/TCP   129m
minio-tenant-1-hl        ClusterIP   None            <none>        9000/TCP            137m

临时访问控制台:

kubectl port-forward  --address 0.0.0.0 svc/minio-tenant-1-console -n minio-tenant-1 9443:9443

使用https://ip:9443访问minio控制台,使用之前拿到的账号密码即可登录。

如果需要永久外部访问控制台,需要手动创建nodePort类型的service(开启了tls):

apiVersion: v1
kind: Service
metadata:
  name: minio-tenant-1-console-external
  namespace: minio-tenant-1
spec:
  type: NodePort
  ports:
  - name: https-console-external
    nodePort: 32443
    port: 9443
    protocol: TCP
    targetPort: 9443
  selector:
    v1.min.io/tenant: minio-tenant-1

使用https://ip:32443访问minio控制台

同理,如果需要外部访问Minio Server,需要创建如下service:

apiVersion: v1
kind: Service
metadata:
  name: minio-external
  namespace: minio-tenant-1
spec:
  type: NodePort
  ports:
  - name: https-external
    nodePort: 31900
    port: 9000
    protocol: TCP
    targetPort: 9000
  selector:
    v1.min.io/tenant: minio-tenant-1

Root账号密码

前面用的账号密码是创建租户时默认创建的,如果你需要root账号密码,可以用如下方式获取:

kubectl get secret minio-tenant-1-env-configuration -n minio-tenant-1 -o yaml

需要base64 decode一下:

客户端

命令行客户端mc

安装mc

wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin

设置mc连接到当前集群的minio

mc alias set local https://10.211.55.3:31900 414F9JEUWCKVK3ZYBTB3 VAobHPxAYebixuGHPzgCtpbtsECcIua5NB2mxcNl --insecure

命令中的local只是个名字,你可以改成任意你喜欢的名称,以后mc的任意命令都用这个名称来代指我们部署的这个minio集群。

这也意味着你可以通过mc alias set配置多个minio集群。

最后3个参数:

  • 用户名
  • 密码
  • 跳过https证书认证

然后就可以使用mc命令管理minio了,例如:

# 查看local集群中test这个bucket的对象列表
mc ls local/test --insecure

SDK

minio提供了部分语言的SDK客户端,以Java为例,参考官方文档:Java Client API Reference — MinIO Baremetal Documentation

扩容

要求扩容的机器和硬盘是原来的倍数。

假设新增4台服务器,每台4块硬盘,每块硬盘1T,给新的服务器的每一个硬盘创建pv,参考部署步骤。

可以用operator页面上扩容(推荐):

也可以用扩容命令:

kubectl minio tenant expand minio-tenant-1   \
  --servers                 4                \
  --volumes                 16               \
  --capacity                16Ti             \
  --storage-class           minio-local-storage    \
  --namespace               minio-tenant-1
  
 # 查看扩容后的情况
 kubectl minio tenant info minio-tenant-1 \
  --namespace minio-tenant-1

数据恢复

磁盘损坏

当磁盘损坏时,只需更换新磁盘,minio会自动修复,具体步骤如下:

卸载损坏的磁盘

# 假设损坏的磁盘是/dev/sdb
umount /dev/sdb

换上新的磁盘,格式化并挂载

# 根据实际情况修改命令
mkfs.xfs /dev/sdb -L MINIO-DISK1

# vim /etc/fstab
LABEL=MINIO-DISK1      /data/minio-data-1     xfs     defaults,noatime  0  2

# 挂载
mount -a

使用mc admin console观察日志,minio会自动发现新的磁盘并修复数据

使用以下命令监控修复:

mc admin heal

节点损坏

节点损坏是指整个服务器损坏无法使用,只需给该节点装好系统,将节点加入原k8s集群,然后按照修复磁盘的步骤修复即可

升级minio

kubectl minio tenant upgrade minio-tenant-1 \
--namespace minio-tenant-1 \
--image minio/minio:RELEASE.2022-08-25T07-17-05Z

执行完你可能看不到从pod上看不到什么反应,不要慌,它背后在偷偷升级呢,过一会你会看到pod被重新创建了,然后describe pod可以看到使用了新镜像

删除租户

如果使用的pv是recycle或delete策略,删除租户也会删除数据。

我上面的例子用的是retain策略,也就是保留数据。

删除命令如下:

kubectl minio tenant delete minio-tenant-1 --namespace minio-tenant-1
文章作者: 周君
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 周君 !
评论